﻿using DoNet.Common.Extensions;
using Yitter.IdGenerator;

namespace DoNet.Common.Helpers
{
    /// <summary>
    /// Id生成器,包含Guid、时间+随机数、雪花算法生成Id。
    /// </summary>
    public class IdGeneratorHelper
    {
        /// <summary>
        /// 雪花飘逸Id初始化
        /// </summary>
        /// <param name="date">系统开始运行时间</param>
        /// <param name="workerIdBitLength">机器码位长 默认值6，取值范围 [1, 15]（要求：序列数位长+机器码位长不超过22） 建议最大设置为10</param>
        /// <param name="seqBitLength">序列数位长 默认值6，取值范围 [3, 21]（要求：序列数位长+机器码位长不超过22） 默认值6，限制每毫秒生成的ID个数。若生成速度超过5万个/秒，建议加大 SeqBitLength 到 10。</param>
        /// <param name="dataCenterIdBitLength">数据中心ID长度（默认0）</param>
        /// <param name="topOverCostCount">最大漂移次数（含），默认2000，推荐范围500-10000（与计算能力有关）</param>
        /// <param name="timestampType">时间戳类型（0-毫秒，1-秒），默认0</param>
        public static void IdSnowflakeInit(string date = "", byte workerIdBitLength = 6, byte seqBitLength = 6, byte dataCenterIdBitLength = 0, int topOverCostCount = 2000, byte timestampType = 0)
        {
            var idGeneratorOptions = new IdGeneratorOptions();
            idGeneratorOptions.Method = 1; //雪花计算方法 （1-漂移算法|2-传统算法），默认1
            idGeneratorOptions.WorkerId = 1; //机器码 与 WorkerIdBitLength 有关系
            idGeneratorOptions.WorkerIdBitLength = workerIdBitLength; // 机器码位长 默认值6，取值范围 [1, 15]（要求：序列数位长+机器码位长不超过22） 建议最大设置为10
            idGeneratorOptions.SeqBitLength = seqBitLength; //序列数位长 默认值6，取值范围 [3, 21]（要求：序列数位长+机器码位长不超过22） 默认值6，限制每毫秒生成的ID个数。若生成速度超过5万个/秒，建议加大 SeqBitLength 到 10。
            idGeneratorOptions.DataCenterId = 0; //数据中心ID（默认0）
            idGeneratorOptions.DataCenterIdBitLength = dataCenterIdBitLength; //数据中心ID长度（默认0）
            idGeneratorOptions.TopOverCostCount = topOverCostCount; //最大漂移次数（含），默认2000，推荐范围500-10000（与计算能力有关）
            idGeneratorOptions.BaseTime = date.ObjectToDateTime(DateTime.Now).ToUniversalTime(); //基础时间（UTC格式）不能超过当前系统时间
            idGeneratorOptions.MaxSeqNumber = 0; //最大序列数（含） 置范围 [MinSeqNumber, 2^SeqBitLength-1]，默认值0，表示最大序列数取最大值（2^SeqBitLength-1]）
            idGeneratorOptions.MinSeqNumber = 5; //最小序列数（含）默认值5，取值范围 [5, MaxSeqNumber]，每毫秒的前5个序列数对应编号0-4是保留位，其中1-4是时间回拨相应预留位，0是手工新值预留位
            idGeneratorOptions.TimestampType = timestampType; //时间戳类型（0-毫秒，1-秒），默认0
            //idGeneratorOptions.SleepTime = TimeSpan.FromMilliseconds(500); //在使用漂移算法时启动的休眠时间，默认500毫秒
            YitIdHelper.SetIdGenerator(idGeneratorOptions);
        }

        #region 自动生成编号
        /// <summary>
        /// 表示全局唯一标识符 (GUID)。
        /// </summary>
        /// <returns></returns>
        public static string GuId()
        {
            return Guid.NewGuid().ToString();
        }
        /// <summary>
        /// 自动生成编号/唯一订单号生成，时间戳+随机数，时间戳精确到毫秒，形如2020052113254137177350
        /// </summary>
        /// <returns></returns>
        public static string CreateNo()
        {
            string strRandom = Random.Shared.Next(10000, 99999).ToString(); //生成随机编号 
            return DateTime.Now.ToString("yyyyMMddHHmmssffff") + strRandom;
        }

        /// <summary>
        /// 自动生成编号/唯一订单号生成，时间戳+随机数，时间戳精确到毫秒，形如20052113254137177350
        /// </summary>
        /// <returns></returns>
        public static long CreateNoLong()
        {
            string strRandom = Random.Shared.Next(10000, 99999).ToString(); //生成随机编号 
            string code = DateTime.Now.ToString("yyMMddHHmmssffff") + strRandom;//形如20052113254137177350
            return code.ObjectToLong();
        }

        /// <summary>
        /// 雪花飘逸算法生成ID
        /// </summary>
        public static long IdSnowflake()
        {
            return YitIdHelper.NextId();
        }
        #endregion
    }
}
